#include "hue_feat_def.hpp"
#include "hue_feat_impl.hpp"

#include "BoT_def.hpp"
#include "BoT_impl.hpp"

inline
features_colBoT::features_colBoT(const std::string in_path, const std::string  in_actionNames, const std::string  in_viNames, 
				 const std::string  in_viList, const int in_col, const int in_row)
:path(in_path), actionNames(in_actionNames), viNames(in_viNames), viList(in_viList), col(in_col), row(in_row)
{
  
}

inline
void
features_colBoT::start_colBoT(const int in_nBins, const std::string in_feat_path)
{
  feat_path = in_feat_path;
  nBins = in_nBins; // The hue component is quantised to 16 bins. It can be an input :). Also used for BoT
  
  //Creating the Dictionary for BoT: Como hacer esto mejor??
  cout << "Creating the Dictionary for BoT" << endl;
  BoT my_BoF(nBins, row, col);
  my_BoF.create_dictionary("./dictionary/list.txt");
  cout << "end.." << endl;
  
  std::stringstream tmp_ss;
  tmp_ss << path << actionNames;
  actions.load(tmp_ss.str());
  actions.print("All actions");
  
  //actions.n_rows;
  for (uword act = 0 ; act < actions.n_rows; ++act) {
    feature_actiongroup(act);
  }
  
}

inline
void
features_colBoT::feature_actiongroup(uword act){
  
  std::stringstream tmp_ss2;
  tmp_ss2 << path << actions(act) << viNames;
  vigroup.load(tmp_ss2.str());
  
  //vigroup.n_rows
  for(uword vg = 0 ; vg< vigroup.n_rows; ++vg) {
    std::stringstream tmp_ss3;
    tmp_ss3 << path << actions(act) << vigroup(vg) << viList;
    cout << tmp_ss3.str() << endl;
    vilist.load(tmp_ss3.str());
    vilist.print("List in this folder");
    
    // vilist.n_rows;
    fea_group.set_size(vilist.n_rows);
    
    for ( uword l = 0; l<vilist.n_rows; ++l ){
      std::stringstream tmp_ss4;
      tmp_ss4 << path << actions(act) << vigroup(vg) << vilist(l);
      cout << vilist(l) << endl;
      fea_group(l)= feature_video(tmp_ss4.str());
    }
    std::string gname = vigroup(vg);
    
    std::string gname2 =  gname.substr(0, gname.size()-1);
    cout << vigroup(vg) << endl;
    cout << gname2 << endl;
    std::stringstream saving_group;
    saving_group << feat_path << gname2;
    cout << "Saving in ..." << saving_group.str()<< endl;
    fea_group.save(saving_group.str());
    //getchar();
  }
  
  
}


//Forming a covariance matrix with all vectors. DO the same for BoT
inline 
vec
features_colBoT::feature_video(std::string one_video)
{
  cv::VideoCapture capVideo(one_video);
  //cout << one_video << endl;
  //double fps = capVideo.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
  //cout << "Frame per seconds : " << fps << endl;
  
  //cv::namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
  //double frmcount = capVideo.get(CV_CAP_PROP_FRAME_COUNT);
  //cout << "# of frames is: " << frmcount << endl;
  
  if( !capVideo.isOpened() )
  {
    cout << "Video couldn't be opened" << endl;
    return 0;
  }
  
  cv::Mat frame;
  //cv::Mat prevgray, gray, flow, cflow, frame, prevflow;
  //cv::Mat ixMat, iyMat, ixxMat, iyyMat;
  //cv::namedWindow("My Video", 1);
  //running_stat_vec<vec> stats_video(true);
  int t = 0;
  hue_features hue_feat(nBins);
  BoT my_BoF(nBins, row, col);
  vec bot_color; 
  bot_color.zeros(nBins*2); 
  
  
  for(;;){
    //capVideo >> frame;
    
    bool bSuccess = capVideo.read(frame); // read a new frame from video
    
    if (!bSuccess) //if not success, break loop
	{
	  //cout << "Cannot read the frame from video file" << endl;
	  break;
	}
	t++;
    //cout << frame.rows << endl;
	
	//Por Aqui Voy. Tal vez voy a quitar lo de stats_video. Y usar SVM en OpenCV
	///Hue
	vec hist_vec_frame = hue_feat.hist_Hue(frame);
	//hist_vec_frame.t().print("Hue current frame");
	//stats_video(hist_vec_frame);
	
	///BoT_def
	vec BoT_vec_frame = my_BoF.calculate_features(frame);
	//BoT_vec_frame.t().print("BoT current frame");
	//getchar();
	
	bot_color.subvec(0,nBins-1) = hist_vec_frame;
	bot_color.subvec(nBins, nBins*2 -1) = BoT_vec_frame;
	//bot_color.t().print("Both");
	//getchar();
	bot_color +=bot_color;
	///http://docs.opencv.org/master/modules/ml/doc/support_vector_machines.html
	
  }
  
  bot_color = bot_color/t;
  return bot_color;
}


